// INotifier.cpp: implementation of the INotifier class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SFDL3.h"
#include "INotifier.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


// Notification manager

CNotifyManager::~CNotifyManager()
{
	while(!m_TNs.empty())
	{
		delete m_TNs.top().pNotifier;
		m_TNs.pop();
	}
}

void CNotifyManager::AddNotifier( INotifier* pNotifier )
{
	CTime now=CTime::GetCurrentTime();
	CTime notiTime=pNotifier->GetNextNotifyTime(now);

	TimeNotifier tn;
	tn.time=notiTime;
	tn.pNotifier=pNotifier;
	m_TNs.push(tn);
}

void CNotifyManager::Update(CAgentCtlCharacterEx* pCharacter)
{
	CTime now=CTime::GetCurrentTime();

	while(!m_TNs.empty() && now>m_TNs.top().time)
	{
		INotifier* pNotifier=m_TNs.top().pNotifier;

		pNotifier->Notify(pCharacter);

		// add back to the queue
		m_TNs.pop();
		AddNotifier(pNotifier);
	}
}

// concrete notifiers

CTime CDrinkNotifier::GetNextNotifyTime( const CTime& now )
{
	CTimeSpan span(0,1,0,5);
	return now+span;
}

void CDrinkNotifier::Notify( CAgentCtlCharacterEx* pChacter )
{
	if (!pChacter->GetVisible())
	{
		pChacter->Show(_variant_t(false));
	}

	char* vszWords[]=
	{
		"Are you thirsty?",
		"Would a cup of warm water be ok?",
		"Do you need a drink?"
	};

	int iChoice=rand()%3;
	
	pChacter->Speak(_variant_t(vszWords[iChoice]), _variant_t());
}

CTime CPhysicalActiveNotifier::GetNextNotifyTime( const CTime& now )
{
	CTimeSpan span(0,0,20,0);
	return now+span;
}

void CPhysicalActiveNotifier::Notify( CAgentCtlCharacterEx* pChacter )
{
	if (!pChacter->GetVisible())
	{
		pChacter->Show(_variant_t(false));
	}
	
	pChacter->Speak(_variant_t("How do you feel?"), _variant_t());
	pChacter->Speak(_variant_t("Energetic, just so so, or a little bad?"), _variant_t());
}


CTime CSleepNotifier::GetNextNotifyTime( const CTime& now )
{
	if (now.GetHour()>=m_pConfig->m_LatestSleepHour)
	{
		return now+CTimeSpan(0,0,m_pConfig->m_SleepNotiInterval,0);
	}
	else
	{
		return CTime(now.GetYear(), now.GetMonth(),now.GetDay(),m_pConfig->m_LatestSleepHour,0,0);
	}
}

void CSleepNotifier::Notify( CAgentCtlCharacterEx* pChacter )
{
	if (!pChacter->GetVisible())
	{
		pChacter->Show(_variant_t(false));
	}
	
	pChacter->Speak(_variant_t("You may hurt your health badly!"), _variant_t());
	pChacter->Speak(_variant_t("You should stop work imediately!"), _variant_t());
}